package com.cjt2325.cameralibrary;

import com.cjt2325.cameralibrary.listener.JCameraListener;
import com.cjt2325.cameralibrary.listener.ClickListener;
import com.cjt2325.cameralibrary.listener.IImageArrivalListenerImpl;
import com.cjt2325.cameralibrary.listener.ErrorListener;
import com.cjt2325.cameralibrary.listener.TypeListener;
import com.cjt2325.cameralibrary.listener.CaptureListener;
import com.cjt2325.cameralibrary.state.CameraMachine;
import com.cjt2325.cameralibrary.util.FileUtil;
import com.cjt2325.cameralibrary.util.ScreenUtils;
import com.cjt2325.cameralibrary.util.LogUtil;
import com.cjt2325.cameralibrary.util.ResUtils;
import com.cjt2325.cameralibrary.util.CheckPermission;

import com.cjt2325.cameralibrary.view.CameraView;

import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorProperty;

import ohos.agp.components.StackLayout;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.components.AttrSet;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.ComponentContainer;

import ohos.agp.components.element.Element;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.service.DisplayAttributes;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.global.configuration.Configuration;
import ohos.media.audio.AudioManager;
import ohos.media.camera.params.Metadata;
import ohos.media.common.Source;
import ohos.media.image.ImageReceiver;
import ohos.media.image.PixelMap;
import ohos.media.image.common.ImageFormat;
import ohos.media.player.Player;
import ohos.multimodalinput.event.TouchEvent;
import ohos.utils.net.Uri;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileDescriptor;
import java.io.IOException;

import java.util.Optional;

public class JCameraView extends StackLayout
        implements CameraInterface.CameraOpenOverCallback,
        SurfaceOps.Callback,
        CameraView,
        Component.TouchEventListener {
    /**
     * 拍照浏览时候的类型
     */
    public static final int TYPE_PICTURE = 0x001;
    public static final int TYPE_VIDEO = 0x002;
    public static final int TYPE_SHORT = 0x003;
    public static final int TYPE_DEFAULT = 0x004;

    // 录制视频比特率
    public static final int MEDIA_QUALITY_HIGH = 20 * 100000;
    public static final int MEDIA_QUALITY_MIDDLE = 16 * 100000;
    public static final int MEDIA_QUALITY_LOW = 12 * 100000;
    public static final int MEDIA_QUALITY_POOR = 8 * 100000;
    public static final int MEDIA_QUALITY_FUNNY = 4 * 100000;
    public static final int MEDIA_QUALITY_DESPAIR = 2 * 100000;
    public static final int MEDIA_QUALITY_SORRY = 1 * 80000;

    public static final int BUTTON_STATE_ONLY_CAPTURE = 0x101; // 只能拍照
    public static final int BUTTON_STATE_ONLY_RECORDER = 0x102; // 只能录像
    public static final int BUTTON_STATE_BOTH = 0x103; // 两者都可以


    private static final String TAG = "JCameraView";

    private static final int IMAGE_RCV_CAPACITY = 5;

    /**
     * 闪关灯状态
     */
    private static final int TYPE_FLASH_AUTO = 0x021;
    private static final int TYPE_FLASH_ON = 0x022;
    private static final int TYPE_FLASH_OFF = 0x023;
    private int type_flash = TYPE_FLASH_OFF;

    // Camera状态机
    private CameraMachine mMachine;
    // 回调监听
    private JCameraListener mJCameraListener;
    private ClickListener mLeftClickListener;
    private ClickListener mRightClickListener;
    private EventHandler mHandler;
    private Context mContext;
    private StackLayout mVideoView;
    private Image mPhoto;
    private Image mSwitchCamera;
    private Image mFlashLamp;
    private CaptureLayout mCaptureLayout;
    private FocusView mFocusView;
    private Player mMediaPlayer;

    private int mLayout_width;
    private float mScreenProp = 0f;

    private PixelMap mCaptureBitmap; // 捕获的图片
    private String mVideoUrl; // 视频URL

    // 切换摄像头按钮的参数
    private int mIconSrc = 0; // 图标资源
    private int mIconLeft = 0; // 左图标
    private int mIconRight = 0; // 右图标
    private int mRecordDuration = 0; // 录制时间

    // 缩放梯度
    private int mZoomGradient = 0;
    private float mFirstTouchLength = 0;
    private SurfaceProvider mProvider;
    private ImageReceiver mImageReceiver;

    private boolean isFirstTouch = true;
    private boolean isPlay = false;
    private boolean isCameraDestroyed = false;
    private ErrorListener mErrorListener;

    /**
     * 设置切换摄像头的图标
     *
     * @param iconSrc int
     */
    public void setIconSrc(int iconSrc) {
        this.mIconSrc = iconSrc;
        if (mSwitchCamera != null && iconSrc > 0) {
            mSwitchCamera.setPixelMap(iconSrc);
        }
    }

    /**
     * 设置自定义图标
     *
     * @param iconLeft  int
     * @param iconRight int
     */
    public void setIconLeftAndRight(int iconLeft, int iconRight) {
        this.mIconLeft = iconLeft;
        this.mIconRight = iconRight;
        if (mCaptureLayout != null) {
            mCaptureLayout.setIconSrc(iconLeft, iconRight);
        }
    }

    /**
     * 设置自定义图标
     *
     * @param leftElement  Element
     * @param rightElement Element
     */
    public void setIconLeftAndRight(Element leftElement, Element rightElement) {
        if (mCaptureLayout != null) {
            mCaptureLayout.setIconSrc(leftElement, rightElement);
        }
    }

    /**
     * 设置最大的录制时长 ms
     *
     * @param duration int
     */
    public void setDuration(int duration) {
        this.mRecordDuration = duration;
        if (mCaptureLayout != null) {
            mCaptureLayout.setDuration(duration);
        }
    }

    public JCameraView(Context context) {
        this(context, null);
    }

    public JCameraView(Context context, AttrSet attrs) {
        this(context, attrs, "");
    }

    public JCameraView(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        if (CheckPermission.checkPermission(mContext)) {
            initData();
            initView();
        }
    }

    private void initData() {
        FileUtil.initPath(mContext);

        mLayout_width = ScreenUtils.getScreenWidth(mContext);
        float screenHeight = ScreenUtils.getScreenHeight(mContext);

        if (mScreenProp == 0) {
            mScreenProp = screenHeight / mLayout_width;
        }
        LogUtil.error(LogUtil.DEFAULT_TAG, "screenProp:" + mScreenProp);

        mImageReceiver =
                ImageReceiver.create(
                        mLayout_width, ScreenUtils.getScreenHeight(mContext), ImageFormat.JPEG, IMAGE_RCV_CAPACITY);

        // 缩放梯度
        mZoomGradient = (int) (mLayout_width / 16f);
        mMachine = new CameraMachine(getContext(), this, this);

        mImageReceiver.setImageArrivalListener(new IImageArrivalListenerImpl(mMachine));
    }

    private void initView() {
        Component view = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_camera_view, this, true);
        mVideoView = (StackLayout) view.findComponentById(ResourceTable.Id_video_preview);
        initSurface();
        mPhoto = (Image) view.findComponentById(ResourceTable.Id_image_photo);
        mSwitchCamera = (Image) view.findComponentById(ResourceTable.Id_image_switch);
        mFlashLamp = (Image) view.findComponentById(ResourceTable.Id_image_flash);
        setFlashRes();
        mFlashLamp.setClickedListener(
                component -> {
                    type_flash++;
                    if (type_flash > 0x023) {
                        type_flash = TYPE_FLASH_AUTO;
                    }
                    setFlashRes();
                });
        mCaptureLayout = (CaptureLayout) view.findComponentById(ResourceTable.Id_capture_layout);
        mCaptureLayout.setDuration(mRecordDuration);
        mCaptureLayout.setIconSrc(mIconLeft, mIconRight);
        mFocusView = (FocusView) view.findComponentById(ResourceTable.Id_fouce_view);
        reqCaptureAndFocusSize();
        // 切换摄像头
        mSwitchCamera.setClickedListener(component -> mMachine.switchCamera(getVideoHolder(), mScreenProp));
        addCaptureListener();
        addConfirmOrCancel();
        mCaptureLayout.setLeftClickListener(
                () -> {
                    if (mLeftClickListener != null) {
                        mLeftClickListener.onClick();
                    }
                });
        mCaptureLayout.setRightClickListener(
                () -> {
                    if (mRightClickListener != null) {
                        mRightClickListener.onClick();
                    }
                });
        LogUtil.error(LogUtil.DEFAULT_TAG, "initView end");
    }

    private void addConfirmOrCancel() {
        if (mCaptureLayout == null) {
            return;
        }
        // 确认 取消
        mCaptureLayout.setTypeListener(
                new TypeListener() {
                    @Override
                    public void cancel(boolean cancel) {
                        if (cancel) {
                            CameraInterface.getInstance().reOpenCamera(mMachine);
                        }
                        mMachine.cancel(getVideoHolder(), mScreenProp);
                    }

                    @Override
                    public void confirm(boolean confirm) {
                        if (confirm) {
                            CameraInterface.getInstance().reOpenCamera(mMachine);
                        }
                        mMachine.confirm();
                    }
                });
    }

    private void addCaptureListener() {
        if (mCaptureLayout == null) {
            return;
        }
        // 拍照 录像
        mCaptureLayout.setCaptureListener(
                new CaptureListener() {
                    @Override
                    public void takePictures() {
                        LogUtil.info(LogUtil.DEFAULT_TAG, "click takePictures");
                        mSwitchCamera.setVisibility(INVISIBLE);
                        mFlashLamp.setVisibility(INVISIBLE);
                        mMachine.capture();
                    }

                    @Override
                    public void recordStart() {
                        mSwitchCamera.setVisibility(INVISIBLE);
                        mFlashLamp.setVisibility(INVISIBLE);
                        mMachine.record();
                    }

                    @Override
                    public void recordShort(final long time) {
                        mCaptureLayout.setTextWithAnimation("录制时间过短");
                        mSwitchCamera.setVisibility(VISIBLE);
                        mFlashLamp.setVisibility(VISIBLE);
                        postDelayed(() -> mMachine.stopRecord(true, time), 1500 - time);
                    }

                    @Override
                    public void recordEnd(long time) {
                        mMachine.stopRecord(false, time);
                    }

                    @Override
                    public void recordZoom(float zoom) {
                        mMachine.zoom(zoom, CameraInterface.TYPE_RECORDER);
                    }

                    @Override
                    public void onError(String errorMessage, int type) {
                        if (mErrorListener != null) {
                            mErrorListener.onError(errorMessage, type);
                        }
                    }
                });
    }

    private void reqCaptureAndFocusSize() {
        DisplayAttributes displayAttributes =
                DisplayManager.getInstance().getDefaultDisplay(getContext()).get().getAttributes();
        int screenWidth = displayAttributes.width;
        int layoutWidth;
        if (getResourceManager().getConfiguration().direction == Configuration.DIRECTION_VERTICAL) {
            layoutWidth = screenWidth;
        } else {
            layoutWidth = screenWidth / 2;
        }
        int buttonSize = (int) (layoutWidth / 4.5f);
        int layoutHeight = buttonSize + (buttonSize / 5) * 2 + 100;
        LayoutConfig config = (LayoutConfig) mCaptureLayout.getLayoutConfig();
        config.height = layoutHeight;
        config.width = layoutWidth;
        mCaptureLayout.setLayoutConfig(config);

        LayoutConfig focusViewLayoutConfig = (LayoutConfig) mFocusView.getLayoutConfig();
        focusViewLayoutConfig.width = screenWidth / 3;
        focusViewLayoutConfig.height = screenWidth / 3;
        mFocusView.setLayoutConfig(focusViewLayoutConfig);
    }

    private void postDelayed(Runnable runnable, long delayMills) {
        if (mHandler == null) {
            mHandler = new EventHandler(EventRunner.getMainEventRunner());
        }
        mHandler.postTask(runnable, delayMills);
    }

    @Override
    public void cameraHasOpened() {
        CameraInterface.getInstance().doStartPreview(getVideoHolder(), mScreenProp);
    }

    @Override
    public SurfaceProvider getSurfaceProvider() {
        return mProvider;
    }

    @Override
    public ImageReceiver getImageReceiver() {
        return mImageReceiver;
    }

    @Override
    public Context getAppContext() {
        return mContext;
    }

    private void reInitStatus() {
        resetState(TYPE_DEFAULT); // 重置状态
        CameraInterface.getInstance().registerSensorManager();
        CameraInterface.getInstance().setSwitchView(mSwitchCamera, mFlashLamp);
        mMachine.start(getVideoHolder(), mScreenProp);
    }

    // 生命周期onResume
    public void onResume() {
        LogUtil.info(LogUtil.DEFAULT_TAG, "JCameraView onResume,isCameraDestroyed:" + isCameraDestroyed);
        if (isCameraDestroyed) {
            initSurface();
        } else {
            reInitStatus();
        }
    }

    // 生命周期onPause
    public void onPause() {
        LogUtil.info(LogUtil.DEFAULT_TAG, "JCameraView onPause");
        stopVideo();
        resetState(TYPE_PICTURE);
        CameraInterface.getInstance().isPreview(false);
        CameraInterface.getInstance().unregisterSensorManager();
    }

    private void onDestroyed() {
        isCameraDestroyed = true;
        isPlay = false;
        stopVideo();
        resetState(TYPE_PICTURE);
        CameraInterface.getInstance().isPreview(false);
        CameraInterface.getInstance().unregisterSensorManager();
        CameraInterface.getInstance().doDestroyCamera();
    }

    @Override
    public void surfaceCreated(SurfaceOps surfaceOps) {
        LogUtil.info(LogUtil.DEFAULT_TAG, "JCameraView SurfaceCreated isPlay:" + isPlay);
        if (isPlay) {
            startPlayVideo();
            return;
        }
        CameraInterface.getInstance().doOpenCamera(JCameraView.this, mMachine);
        if (isCameraDestroyed) {
            reInitStatus();
        }
        isCameraDestroyed = false;
    }

    @Override
    public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {
    }

    @Override
    public void surfaceDestroyed(SurfaceOps surfaceOps) {
        LogUtil.info(LogUtil.DEFAULT_TAG, "JCameraView SurfaceDestroyed");
        onDestroyed();
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent event) {
        switch (event.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                if (event.getPointerCount() == 1) {
                    // 显示对焦指示器
                    float eventX = event.getPointerPosition(0).getX();
                    float eventY = event.getPointerPosition(0).getY();
                    setFocusViewWidthAnimation(eventX, eventY);
                }
                break;
            case TouchEvent.POINT_MOVE:
                if (event.getPointerCount() == 1) {
                    isFirstTouch = true;
                }
                if (event.getPointerCount() == 2) {
                    float point1X = event.getPointerPosition(0).getX();
                    float point1Y = event.getPointerPosition(0).getY();

                    float point2X = event.getPointerPosition(1).getX();
                    float point2Y = event.getPointerPosition(1).getY();

                    float result =
                            (float) Math.sqrt(Math.pow(point1X - point2X, 2) + Math.pow(point1Y - point2Y, 2));

                    if (isFirstTouch) {
                        mFirstTouchLength = result;
                        isFirstTouch = false;
                    }
                    if ((int) (result - mFirstTouchLength) / mZoomGradient != 0) {
                        isFirstTouch = true;
                        mMachine.zoom(result - mFirstTouchLength, CameraInterface.TYPE_CAPTURE);
                    }
                }
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                isFirstTouch = true;
                break;
        }
        return true;
    }

    // 对焦框指示器动画
    private void setFocusViewWidthAnimation(float xx, float yy) {
        mMachine.focus(xx, yy, () -> mFocusView.setVisibility(HIDE));
    }

    private void updateVideoViewSize(float videoWidth, float videoHeight) {
        if (videoWidth > videoHeight) {
            int height = (int) ((videoHeight / videoWidth) * getWidth());
            LayoutConfig config = new LayoutConfig(LayoutConfig.MATCH_PARENT, height);
            config.alignment = LayoutAlignment.CENTER;
            mVideoView.setLayoutConfig(config);
        }
    }

    /**
     * set SaveVideo Path
     *
     * @param path String
     */
    public void setSaveVideoPath(String path) {
        CameraInterface.getInstance().setSaveVideoPath(path);
    }

    /**
     * set JCameraListener
     *
     * @param jCameraListener JCameraListener
     */
    public void setJCameraListener(JCameraListener jCameraListener) {
        this.mJCameraListener = jCameraListener;
    }

    /**
     * 启动Camera错误回调
     *
     * @param errorListener ErrorListener
     */
    public void setErrorListener(ErrorListener errorListener) {
        this.mErrorListener = errorListener;
        CameraInterface.getInstance().setErrorListener(errorListener);
    }

    /**
     * 设置CaptureButton功能（拍照和录像）
     *
     * @param state int
     */
    public void setFeatures(int state) {
        this.mCaptureLayout.setButtonFeatures(state);
    }

    /**
     * 设置录制质量
     *
     * @param quality int
     */
    public void setMediaQuality(int quality) {
        CameraInterface.getInstance().setMediaQuality(quality);
    }

    @Override
    public void resetState(int type) {
        if (mVideoView == null) {
            return;
        }
        switch (type) {
            case TYPE_VIDEO:
                stopVideo(); // 停止播放
                // 初始化VideoView
                FileUtil.deleteFile(mVideoUrl);
                mVideoView.setLayoutConfig(
                        new StackLayout.LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT));
                mMachine.start(getVideoHolder(), mScreenProp);
                break;
            case TYPE_PICTURE:
                mPhoto.setVisibility(INVISIBLE);
                break;
            case TYPE_SHORT:
                break;
            case TYPE_DEFAULT:
                mVideoView.setLayoutConfig(
                        new StackLayout.LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT));
                break;
        }
        mSwitchCamera.setVisibility(VISIBLE);
        mFlashLamp.setVisibility(VISIBLE);
        mCaptureLayout.resetCaptureLayout();
    }

    @Override
    public void confirmState(int type) {
        LogUtil.error(LogUtil.DEFAULT_TAG, "confirmState type:" + type);
        switch (type) {
            case TYPE_VIDEO:
                stopVideo(); // 停止播放
                mVideoView.setLayoutConfig(
                        new StackLayout.LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT));
                mMachine.start(getVideoHolder(), mScreenProp);
                if (mJCameraListener != null) {
                    mJCameraListener.recordSuccess(mVideoUrl);
                }
                break;
            case TYPE_PICTURE:
                mPhoto.setVisibility(INVISIBLE);
                if (mJCameraListener != null) {
                    mJCameraListener.captureSuccess(mCaptureBitmap);
                }
                break;
            case TYPE_SHORT:
                break;
            case TYPE_DEFAULT:
                break;
        }
        mCaptureLayout.resetCaptureLayout();
    }

    @Override
    public void showPicture(PixelMap bitmap, boolean isVertical) {
//        if (isVertical) {
//            mPhoto.setScaleMode(Image.ScaleMode.STRETCH);
//        } else {
//            mPhoto.setScaleMode(Image.ScaleMode.ZOOM_CENTER);
//        }
        mCaptureBitmap = bitmap;
        mPhoto.setPixelMap(bitmap);
        mPhoto.setVisibility(VISIBLE);
        mCaptureLayout.startAlphaAnimation();
        mCaptureLayout.startTypeBtnAnimator();
    }

    private void initSurface() {
        if (mVideoView != null && mVideoView.getChildCount() > 0) {
            mVideoView.removeAllComponents();
        }
        if (mProvider != null) {
            mProvider.release();
            mProvider = null;
        }
        mProvider = new SurfaceProvider(mContext);
        StackLayout.LayoutConfig params =
                new StackLayout.LayoutConfig(
                        ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT);

        mProvider.setLayoutConfig(params);
        mProvider.pinToZTop(false);
        mProvider.getSurfaceOps().get().addCallback(this);

        if (mVideoView != null) {
            mVideoView.addComponent(mProvider);
        }
        LogUtil.info(LogUtil.DEFAULT_TAG, "initSurface success");
    }

    private Surface getSurface() {
        if (mProvider == null) {
            return null;
        }
        Surface surface = null;
        Optional<SurfaceOps> surfaceOps = mProvider.getSurfaceOps();
        if (surfaceOps.isPresent()) {
            surface = surfaceOps.get().getSurface();
        }
        return surface;
    }

    private SurfaceOps getVideoHolder() {
        Component component = mVideoView.getComponentAt(0);
        if (component instanceof SurfaceProvider) {
            SurfaceProvider surfaceProvider = (SurfaceProvider) component;
            Optional<SurfaceOps> surfaceOps = surfaceProvider.getSurfaceOps();
            return surfaceOps.orElse(null);
        }
        return null;
    }

    public void setClickButtonColor(int inColor, int outColor, int proColor) {
        if (mCaptureLayout == null) {
            return;
        }
        mCaptureLayout.setButtonColor(inColor, outColor, proColor);
    }

    @Override
    public void playVideo(final String url) {
        LogUtil.error(LogUtil.DEFAULT_TAG, "playVideo url:" + Uri.parse(url).toString());
        isPlay = true;
        initSurface();
        mVideoUrl = url;
    }

    private void startPlayVideo() {
        new Thread(
                () -> {
                    try {
                        if (mMediaPlayer == null) {
                            mMediaPlayer = new Player(mContext);
                        } else {
                            mMediaPlayer.reset();
                        }
                        File file = new File(mVideoUrl);
                        if (!file.exists() || file.length() == 0) {
                            return;
                        }
                        FileInputStream in = new FileInputStream(file);
                        FileDescriptor fd = in.getFD(); // 从输入流获取FD对象
                        Source source = new Source(fd);
                        Surface surface = getSurface();
                        mMediaPlayer.setSource(source);
                        mMediaPlayer.setVideoSurface(surface);
                        mMediaPlayer.setVideoScaleType(Player.VIDEO_SCALE_TYPE_FIT);
                        addPlayerCallBack();
                        mMediaPlayer.setAudioStreamType(AudioManager.AudioVolumeType.STREAM_MUSIC.getValue());
                        mMediaPlayer.enableSingleLooping(true);
                        mMediaPlayer.prepare();
                        LogUtil.error(LogUtil.DEFAULT_TAG, "playVideo play end");
                    } catch (IOException e) {
                        LogUtil.error(LogUtil.DEFAULT_TAG, "playVideo e:" + e.getMessage());
                    }
                })
                .start();
    }

    private void addPlayerCallBack() {
        if (mMediaPlayer == null) {
            return;
        }
        mMediaPlayer.setPlayerCallback(
                new Player.IPlayerCallback() {
                    @Override
                    public void onPrepared() {
                        mMediaPlayer.play();
                    }

                    @Override
                    public void onMessage(int i, int i1) {
                    }

                    @Override
                    public void onError(int i, int i1) {
                        LogUtil.error(
                                LogUtil.DEFAULT_TAG, "playVideo mMediaPlayer onError i:" + i);
                    }

                    @Override
                    public void onResolutionChanged(int i, int i1) {
                        updateVideoViewSize(
                                mMediaPlayer.getVideoWidth(), mMediaPlayer.getVideoHeight());
                    }

                    @Override
                    public void onPlayBackComplete() {
                    }

                    @Override
                    public void onRewindToComplete() {
                    }

                    @Override
                    public void onBufferingChange(int i) {
                    }

                    @Override
                    public void onNewTimedMetaData(
                            Player.MediaTimedMetaData mediaTimedMetaData) {
                    }

                    @Override
                    public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) {
                    }
                });
    }

    @Override
    public void stopVideo() {
        if (mMediaPlayer != null && mMediaPlayer.isNowPlaying()) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    @Override
    public void setTip(String tip) {
        mCaptureLayout.setTip(tip);
    }

    @Override
    public void startPreviewCallback() {
        LogUtil.info(LogUtil.DEFAULT_TAG, "startPreviewCallback");
        handlerFoucs(mFocusView.getWidth() / 2f, mFocusView.getHeight() / 2f);
    }

    @Override
    public boolean handlerFoucs(float pointX, float pointY) {
        if (pointY > mCaptureLayout.getTop()) {
            return false;
        }
        mFocusView.setVisibility(VISIBLE);
        if (pointX < mFocusView.getWidth() / 2f) {
            pointX = mFocusView.getWidth() / 2f;
        }
        if (pointX > mLayout_width - mFocusView.getWidth() / 2f) {
            pointX = mLayout_width - mFocusView.getWidth() / 2f;
        }
        if (pointY < mFocusView.getWidth() / 2f) {
            pointY = mFocusView.getWidth() / 2f;
        }
        if (pointY > mCaptureLayout.getTop() - mFocusView.getWidth() / 2f) {
            pointY = mCaptureLayout.getTop() - mFocusView.getWidth() / 2f;
        }
        mFocusView.setX(pointX - mFocusView.getWidth() / 2f);
        mFocusView.setY(pointY - mFocusView.getHeight() / 2f);

        AnimatorProperty scaleAnimation = new AnimatorProperty(mFocusView);
        scaleAnimation.scaleX(1f).scaleX(0.6f);
        scaleAnimation.scaleY(1f).scaleY(0.6f);

        AnimatorProperty alphaAnimation = new AnimatorProperty(mFocusView);
        alphaAnimation.alpha(1f).alpha(0.4f).alpha(1f).alpha(0.4f).alpha(1f).alpha(0.4f).alpha(1f);

        AnimatorGroup animatorGroup = new AnimatorGroup();
        animatorGroup.runParallel(scaleAnimation, alphaAnimation);
        animatorGroup.setDuration(400);
        animatorGroup.start();
        return true;
    }

    /**
     * set LeftClick Listener
     *
     * @param clickListener ClickListener
     */
    public void setLeftClickListener(ClickListener clickListener) {
        this.mLeftClickListener = clickListener;
    }

    /**
     * set RightClick Listener
     *
     * @param clickListener ClickListener
     */
    public void setRightClickListener(ClickListener clickListener) {
        this.mRightClickListener = clickListener;
    }

    private void setFlashRes() {
        switch (type_flash) {
            case TYPE_FLASH_AUTO:
                mFlashLamp.setImageElement(ResUtils.getVectorDrawable(mContext, ResourceTable.Graphic_ic_flash_auto));
                mMachine.flash(Metadata.FlashMode.FLASH_AUTO);
                break;
            case TYPE_FLASH_ON:
                mFlashLamp.setImageElement(ResUtils.getVectorDrawable(mContext, ResourceTable.Graphic_ic_flash_on));
                mMachine.flash(Metadata.FlashMode.FLASH_OPEN);
                break;
            case TYPE_FLASH_OFF:
                mFlashLamp.setImageElement(ResUtils.getVectorDrawable(mContext, ResourceTable.Graphic_ic_flash_off));
                mMachine.flash(Metadata.FlashMode.FLASH_CLOSE);
                break;
            default:
                break;
        }
        LogUtil.error(LogUtil.DEFAULT_TAG, "setFlashRes end");
    }
}
